﻿using System;
using System.Collections.Generic;
using personalplaner.business.common;
using personalplaner.business.stamm;
using personalplaner.dataprovider;

namespace personalplaner.servicemodel.common
{
    public class PlanAutomation : BaseDataAccess
    {
        public PlanAutomation(ISettingsProvider settings)
			: base(settings)
		{
		}

        /// <summary>
        /// key=dienstid, value=count per day
        /// </summary>
        Dictionary<int, int> dienste;

        /// <summary>
        /// value=count per month
        /// </summary>
        List<int> personen = new List<int>();

        List<int> abteilungen = new List<int>();

        public void ScedulePlan(ArbeitsPlanHeader plan)
        {
            var abts = DataServices.PlanLayoutService.GetAbteilungenInSchema(Settings.DatabaseSettings, plan.SchemaId);
            foreach (var abt in abts)
                abteilungen.Add(abt.AbteilungID);


            int daycount = plan.Bis.Day;
            int month = plan.Bis.Month;
            int year = plan.Bis.Year;
            Random random = new Random();

            foreach (int abteilungid in abteilungen)
            {
                //create list with dienste to
                InitializeDienste(abteilungid, plan.SchemaId);

                //loop for every dienst
                foreach (int dienstid in dienste.Keys)
                {
                    //loop dienst for every day in plan
                    for (int i = 1; i <= daycount; i++)
                    {
                        var date = new DateTime(year, month, i);

                        int countInPlan = DataServices.PlanService.GetDienstCountInPlanPerDay(Settings.DatabaseSettings, dienstid, plan.PlanId, abteilungid, date);

                        //create list with people
                        if (countInPlan < dienste[dienstid])
                        {
                            InitializePersonen(abteilungid, plan.PlanId, date);

                            if (personen.Count > 0)
                            {
                                //loop dienstcount for day
                                while (countInPlan < dienste[dienstid])
                                {
                                    //go down list of people and start adding dienste (random)
                                    int rnd = random.Next(0, personen.Count);

                                    //check if people are free
                                    if (personen.Count > 0)
                                    {
                                        if (DataServices.PlanService.GetDienstCountInPlanPerDay(Settings.DatabaseSettings, plan.PlanId, abteilungid, date, personen[rnd]) < 1)
                                        {
                                            //add dienst to person
                                            DataServices.PlanService.SaveDienstInPlan(Settings.DatabaseSettings, plan.PlanId, personen[rnd], abteilungid, date, dienstid);
                                            //check how many are already planed
                                            countInPlan++;

                                            //create list with people
                                            personen.RemoveAt(rnd);
                                        }
                                    }
                                    else
                                    {
                                        //no more people
                                        countInPlan = dienste[dienstid];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        private void InitializeDienste(int abteilungid, int schemaid)
        {
            dienste = new Dictionary<int, int>();
            var dv = DataServices.DiensteService.GetDiensteInSchema(Settings.DatabaseSettings, schemaid, abteilungid);
            foreach (var row in dv)
                dienste.Add(row.DienstID, row.EinsatzProTag);
        }

        private void InitializePersonen(int abteilungid, int planid, DateTime date)
        {
            var dv = DataServices.PlanService.GetPersonenWithoutDienst(Settings.DatabaseSettings, planid, abteilungid, date);
            personen.Clear();

            if (dv == null)
                return;

            foreach(var prsid in dv)
                personen.Add(prsid);
        }
    }
}
